package systemMapperImpl

import (
	"baize/app/business/system/systemModels"
	"baize/app/datasource"
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type SysMenuMapper struct {
	collection func(ctx context.Context) *mongo.Collection
}

func NewSysMenuMapper(c *mongo.Client) *SysMenuMapper {
	return &SysMenuMapper{
		collection: func(ctx context.Context) *mongo.Collection {
			return c.Database(datasource.SysDatabase).Collection(datasource.Collection["menu"])
		},
	}
}

func (sysMenuMapper *SysMenuMapper) SelectMenuById(ctx context.Context, menuId int64) (menu *systemModels.SysMenuVo) {
	//whereSql := ` where menu_id = ?`
	//menu = new(systemModels.SysMenuVo)
	//err := db.GetContext(ctx, menu, sysMenuDao.selectMenuSql+whereSql, menuId)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return
}

func (sysMenuMapper *SysMenuMapper) SelectMenuList(ctx context.Context, menu *systemModels.SysMenuDQL) (list []*systemModels.SysMenuVo) {
	//whereSql := ``
	//if menu.MenuName != "" {
	//	whereSql += " AND menu_name like concat('%', :menu_name, '%')"
	//}
	//if menu.Visible != "" {
	//	whereSql += " AND Visible = :visible"
	//}
	//if menu.MenuName != "" {
	//	whereSql += "  AND status = :status"
	//}
	//if whereSql != "" {
	//	whereSql = " where " + whereSql[4:]
	//}
	//whereSql += " order by m.parent_id, m.order_num"
	//
	//list = make([]*systemModels.SysMenuVo, 0, 16)
	//err := db.NamedSelectContext(ctx, &list, sysMenuDao.selectMenuSql+whereSql, menu)
	//
	//if err != nil {
	//	panic(err)
	//}

	return list
}

func (sysMenuMapper *SysMenuMapper) SelectMenuListByUserId(ctx context.Context, menu *systemModels.SysMenuDQL) (list []*systemModels.SysMenuVo) {
	//whereSql := ` left join sys_role_menu rm on m.menu_id = rm.menu_id
	//	left join sys_user_role ur on rm.role_id = ur.role_id
	//	left join sys_role ro on ur.role_id = ro.role_id
	//	where ur.user_id = :user_id`
	//if menu.MenuName != "" {
	//	whereSql += " AND menu_name like concat('%', :menu_name, '%')"
	//}
	//if menu.Visible != "" {
	//	whereSql += " AND Visible = :visible"
	//}
	//if menu.MenuName != "" {
	//	whereSql += "  AND status = :status"
	//}
	//whereSql += " m.parent_id, m.order_num"
	//
	//list = make([]*systemModels.SysMenuVo, 0, 16)
	//err := db.NamedSelectContext(ctx, &list, sysMenuDao.selectMenuSql+whereSql, menu)
	//
	//if err != nil {
	//	panic(err)
	//}

	return list
}

func (sysMenuMapper *SysMenuMapper) InsertMenu(ctx context.Context, menu *systemModels.SysMenuVo) {

	//insertStr := fmt.Sprintf(insertSQL, key, value)
	//_, err := db.NamedExecContext(ctx, insertStr, menu)
	//if err != nil {
	//	panic(err)
	//}
	return
}

func (sysMenuMapper *SysMenuMapper) UpdateMenu(ctx context.Context, menu *systemModels.SysMenuVo) {
	updateSQL := `update sys_menu set update_time = now() , update_by = :update_by`

	if menu.ParentId != 0 {
		updateSQL += ",parent_id = :parent_id"
	}
	if menu.MenuName != "" {
		updateSQL += ",menu_name = :menu_name"
	}
	if menu.OrderNum != 0 {
		updateSQL += ",order_num = :order_num"
	}
	if menu.Path != "" {
		updateSQL += ",path = :path"
	}
	if menu.Component != "" {
		updateSQL += ",component = :component"
	}
	if menu.IsFrame != "" {
		updateSQL += ",is_frame = :is_frame"
	}
	if menu.IsCache != "" {
		updateSQL += ",is_cache = :is_cache"
	}
	if menu.MenuType != "" {
		updateSQL += ",menu_type = :menu_type"
	}
	if menu.Visible != "" {
		updateSQL += ",visible = :visible"
	}
	if menu.Status != "" {
		updateSQL += ",status = :status"
	}
	if menu.Perms != "" {
		updateSQL += ",perms = :perms"
	}
	if menu.Icon != "" {
		updateSQL += ",icon = :icon"
	}
	if menu.Status != "" {
		updateSQL += ",status = :status"
	}
	//updateSQL += " where menu_id = :menu_id"
	//
	//_, err := db.NamedExecContext(ctx, updateSQL, menu)
	//if err != nil {
	//	panic(err)
	//}
	return
}

func (sysMenuMapper *SysMenuMapper) DeleteMenuById(ctx context.Context, menuId int64) {
	//_, err := db.ExecContext(ctx, "delete from sys_menu where menu_id = ?", menuId)
	//if err != nil {
	//	panic(err)
	//}
	return
}

func (sysMenuMapper *SysMenuMapper) SelectMenuPermsAll(ctx context.Context) (perms []string) {
	filter := bson.M{"perms": bson.M{"$ne": ""}}
	result, err := sysMenuMapper.collection(ctx).Distinct(ctx, "perms", filter)
	if err != nil {
		panic(err)
	}
	for _, item := range result {
		if str, ok := item.(string); ok {
			perms = append(perms, str)
		}
	}
	return
}

func (sysMenuMapper *SysMenuMapper) SelectMenuTreeAll(ctx context.Context) (sysMenus []*systemModels.SysMenuVo) {
	filter := bson.M{"status": "0", "menu_type": bson.M{"$in": []string{"M", "C"}}}
	opt := &options.FindOptions{}
	opt.SetSort(bson.D{{Key: "parent_id", Value: 1}, {Key: "order_num", Value: 1}})
	cur, err := sysMenuMapper.collection(ctx).Find(ctx, filter, opt)
	if err != nil {
		panic(err)
	}

	defer cur.Close(ctx)
	err = cur.All(context.Background(), &sysMenus)
	if err != nil {
		panic(err)
	}
	return sysMenus
	//whereSql := ` where m.menu_type in ('M', 'C') and m.status = 0
	//	order by m.parent_id, m.order_num`
	//sysMenus = make([]*systemModels.SysMenuVo, 0, 2)
	//err := db.SelectContext(ctx, &sysMenus, sysMenuDao.selectMenuSql+whereSql)
	//if err != nil {
	//	panic(err)
	//}
	return
}
func (sysMenuMapper *SysMenuMapper) SelectMenuTreeByUserId(ctx context.Context, userId int64) (sysMenus []*systemModels.SysMenuVo) {
	//whereSql := ` left join sys_role_menu rm on m.menu_id = rm.menu_id
	//		 left join sys_user_role ur on rm.role_id = ur.role_id
	//		 left join sys_role ro on ur.role_id = ro.role_id
	//		 left join sys_user u on ur.user_id = u.user_id
	//	where u.user_id = ? and m.menu_type in ('M', 'C') and m.status = 0  AND ro.status = 0
	//	order by m.parent_id, m.order_num`
	//sysMenus = make([]*systemModels.SysMenuVo, 0, 2)
	//err := db.SelectContext(ctx, &sysMenus, sysMenuDao.selectMenuSql+whereSql, userId)
	//if err != nil {
	//	panic(err)
	//}
	return
}

func (sysMenuMapper *SysMenuMapper) CheckMenuNameUnique(ctx context.Context, menuName string, parentId int64) int64 {
	var roleId int64 = 0
	//err := db.GetContext(ctx, &roleId, "select menu_id from sys_menu where menu_name=? and parent_id = ?", menuName, parentId)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return roleId
}

func (sysMenuMapper *SysMenuMapper) HasChildByMenuId(ctx context.Context, menuId int64) int {
	var count = 0
	//err := db.GetContext(ctx, &count, "SELECT EXISTS( SELECT 1 FROM sys_menu where parent_id = ?)", menuId)
	//if err != nil && !errors.Is(sql.ErrNoRows, err) {
	//	panic(err)
	//}
	return count
}
func (sysMenuMapper *SysMenuMapper) SelectMenuListByRoleId(ctx context.Context, roleId int64, menuCheckStrictly bool) (roleIds []string) {
	//var err error
	//roleIds = make([]string, 0, 2)
	//sqlstr := `select m.menu_id
	//	from sys_menu m
	//        left join sys_role_menu rm on m.menu_id = rm.menu_id
	//    where rm.role_id = ?`
	//if menuCheckStrictly {
	//	sqlstr += " and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id = rm.menu_id and rm.role_id = ?)"
	//	err = db.SelectContext(ctx, &roleIds, sqlstr, roleId, roleId)
	//} else {
	//	err = db.SelectContext(ctx, &roleIds, sqlstr, roleId)
	//}
	//
	//if err != nil {
	//	panic(err)
	//}
	return
}
